/*

pages.product.detail.em.controllers.js

Author: Byron Salau
Contributors:

This file is part of Blanc

Licenced under the MIT License (MIT)
 
Copyright (C) 2011 - 2012 Codagenic Pty. Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

*/

Blanc.Pages.Products.Detail.Em.controllers = function (namespace)
{

	namespace = namespace || "App";

	var App = global[namespace], 
		
		controllers =
		{
			/*
			* Main Product Controller
			*/
			ProductController: Ember.Object.create({

				// Constructor
				init: function ()
				{
				    this.service = new Codagenic.ProductDataAccess();
				    this.loadProduct();
				},

				on: function(event, target)
				{
					return $(this).bind(event, target);
				},

				_fireEvent: function(event, params)
				{
					$(this).trigger(event, params);
				},

				/* 
				* Properties 
				*/
				product: null,
				productAttributes: [],
				selectedVariation: null,
				selectedQty: 0,
                service: null,

				/*
				* Methods
				*/
				activityIndicator: Ember.Object.create({

					working: false,

					show: function ()
					{
						this.set('working', true);
					},

					hide: function ()
					{
						this.set('working', false);

					}
				}),

				didSelectAttribute: function (sender)
				{
					var v = this.get('selectedVariation'),
						currentAttributes = v.attributes,
						mutableAttributes = Codagenic.A();

					currentAttributes.each(function ()
					{
						mutableAttributes.push({ title: this.title, value: this.value });
					});


					// Mutate the values
					for (var i = 0; i < mutableAttributes.length; i++)
					{
						// Update with new value
						if (mutableAttributes[i].title === sender.title)
						{
							mutableAttributes[i].value = sender.value;
							break;
						}
					}

					// Update variation
					v = this.get('product').findVariationWithAttributes(mutableAttributes);
					if (!v)
					{
						// TODO: Handle no variation found
						return;
					}

					// Set new variation
					this.set('selectedVariation', v);

					// Trigger Our Assets Updated Event
					this._fireEvent('assetsChange');

				},

				assets: function ()
				{
					var variation = this.get('selectedVariation'),
						product = this.get('product'),
						assets = null,
						data = [];

					if (variation && variation.hasAssets())
					{
						//Variation has assets
						assets = variation.getAssets();
					}
					else if (product)
					{
						// No Variation assets so use assets from product level as our fallback
						assets = product.getAssets();
					}
					else
					{
						// Cant do anything without a product or variation
						return data;
					}

					assets.images.each(function ()
					{
						data.push({
							image: this.url + Blanc.Config.ImageDimensions.getParams("detail"),
							thumb: this.url + Blanc.Config.ImageDimensions.getParams("thumb"),
							big: this.url,
							title: this.title,
							description: this.title
						});
					});

					assets.videos.each(function(){
						data.push({
							video: this.url
						});
					});

					//TODO: Do something with documents
					//assets.documents

					return data;
				},

				// Validate the quantity entered by the user
				// @param qty, the value of the quatity to validate
				// @param max, optional, the maximum quantity allowed
				//
				validateQuantity: function (qty, max)
				{
					// Test for number
					if (!Codagenic.isNumber(qty))
					{
						alert('Please enter only numeric characters for quantity');
						return false;
					}

					// Test for positive number
					if (!qty || qty < 1)
					{
						alert('Please enter a quantity');
						return false;
					}

					// Test for stock levels
					if (Codagenic.isSet(max))
					{
						if (qty > max)
						{
							alert('There is not enough stock available, please try entering a lower quantity');
							return false;
						}
					}

					// Passed (Valid)
					this.set('selectedQty', qty);
					return true;
				},

				addSelectedVariationToCartWithQty: function (qty)
				{
				    var self = this,
                        variation = this.get('selectedVariation');

					if (variation === null || !this.validateQuantity(qty, variation.qty))
					{
						return;
					}

					App.Controllers.ProductController.activityIndicator.show();

					self.get("service").addProductToCart(self.get('product').id, self.get('selectedVariation').id, qty, function (data)
					{
					    App.Controllers.ProductController.activityIndicator.hide();
					    Blanc.Pages.Products.Detail.didAddItemToCart(data);
					    App.Controllers.MiniCartController.updateOrderLines(data.orderLines);
					}, function (data)
					{
					    App.Controllers.ProductController.activityIndicator.hide();
					    alert('Failed to add item to your cart. \n\nRequest Status: "' + textStatus + '"');
					});
				},

				addSelectedVariationToWishlistWithQty: function (qty)
				{
				    var self = this,
                       variation = this.get('selectedVariation');

					if (!this.validateQuantity(qty) || variation === null)
					{
					    return;
					}

					App.Controllers.ProductController.activityIndicator.show();

					self.get("service").addProductToWishlist(self.get('product').id, self.get('selectedVariation').id, qty, function (data)
					{
					    var c;

					    if (data)
					    {
					        c = data.totalItems;
					    }

					    Blanc.Pages.Products.Detail.didAddItemToWishlist(c);
					    App.Controllers.ProductController.activityIndicator.hide();
					}, function (e)
					{
					    alert('Failed to add item to your wishlist. \n\nRequest Status: "' + e.status + " " + e.statusText + '"');
					    App.Controllers.ProductController.activityIndicator.hide();
					});
				},

				loadProduct: function ()
				{
				    var self = this,
                        productId = $("div[role='product-detail']").attr('data-id');

				    self.get('activityIndicator').show();

				    // Request the product from the API
				    self.get("service").loadProduct(productId, function (product)
				    {
				        self.get('activityIndicator').hide();

				        var uniqueAttribites = product.listUniqueAttributes(true);

				        uniqueAttribites.each(function ()
				        {
				            switch (this.title.toUpperCase())
				            {
				                case "SIZE":
				                    return this.sortByValues(["XS", "S", "M", "L", "XL", "XXL", "XXXL"]);
				                default:
				                    break;
				            }
				        });

				        self.set('productAttributes', uniqueAttribites);
				        self.set('selectedVariation', product.defaultVariation());
				        self.set('product', product);

				        self._fireEvent('load');
				    });

				}
			}),

			MiniCartController: Ember.Object.create({

				orderLines: null,

				updateOrderLines: function (ol)
				{
					this.set('orderLines', ol);
				}
			})
		};

	return controllers;

};
